﻿using System;
using System.Globalization;
using System.Windows.Data;

namespace Black.SurfaceToolkit.Converters
{
    /// <summary>
    /// Obtient l'angle en fonction de la valeur et de l'angle entre les graduations.
    /// Ne fonctionne sur plusieurs source qu'en <see cref="F:System.Windows.Data.BindingMode.OneWay" /> ou <see cref="F:System.Windows.Data.BindingMode.OneTime" /> (sinon, utilisez une instance par binding effectif).
    /// </summary>
    public class ToAngleConverter : IMultiValueConverter
    {
        #region Accesseurs

        /// <summary>
        /// Obtient ou définit une valeur indiquant si la valeur de retour est l'opposé de l'angle.
        /// </summary>
        public bool Opposite
        {
            get;
            set;
        }

        #endregion

        #region Variables d'instance

        /// <summary>
        /// Se souvient de la dernière valeur des angles entre graduation.
        /// On suppose que cette valeur est moins susceptible de changer que la position.
        /// </summary>
        private double m_dTickAngle = 1.0;

        #endregion

        #region Constructeurs

        /// <summary>
        /// Initalise une nouvelle instance de <see cref="T:Black.SurfaceToolkit.Converters.ToAngleConverter" />.
        /// </summary>
        public ToAngleConverter()
            : base()
        {
        }

        #endregion

        #region Fonctions publiques

        /// <summary>
        /// Obtient l'angle des valeurs spécifiées.
        /// </summary>
        /// <param name="p_oValues">Valeur de l'élément puis angle entre les graduations.</param>
        /// <param name="p_oTargetType">Type de destination.</param>
        /// <param name="p_oParameter">Paramètre de convertion.</param>
        /// <param name="p_oCulture">Culture de convertion.</param>
        /// <returns>Angle des valeurs spécifiées.</returns>
        public object Convert(object[] p_oValues, Type p_oTargetType, object p_oParameter, CultureInfo p_oCulture)
        {
            double dPosition = (double)p_oValues[0];
            this.m_dTickAngle = (double)p_oValues[1];

            double dResult = dPosition * this.m_dTickAngle;

            return (this.Opposite ? -dResult : dResult);
        }

        /// <summary>
        /// Obtient les valeurs de l'angle spécifié.
        /// </summary>
        /// <param name="p_oValue">Angle de l'élément.</param>
        /// <param name="p_oTargetTypes">Types de destination.</param>
        /// <param name="p_oParameter">Paramètre de convertion.</param>
        /// <param name="p_oCulture">Culture de convertion.</param>
        /// <returns>Valeurs de l'angle spécifié.</returns>
        public object[] ConvertBack(object p_oValue, Type[] p_oTargetTypes, object p_oParameter, CultureInfo p_oCulture)
        {
            object[] oResult = new object[2];
            double dValue = (double)p_oValue;

            oResult[0] = (this.Opposite ? -dValue : dValue) / this.m_dTickAngle;
            oResult[1] = this.m_dTickAngle;

            return (oResult);
        }

        #endregion
    }
}
